#ifdef ARDUINO_ARCH_ESP8266

#include <logger_rte.h>
#include "boardbase.h"
#include "retain_lfs.h"

int writeFlash(uint32_t adr, const char *buf, int len) {
//    if (adr & 0x3) {
//        logger.error("align error");
//        return -1;
//    }
    // if ((uint32_t)buf & 0x3)
    // {
    //     logger.error("buf alignment error");
    //     return -2;
    // }
//    HAL_FLASH_Unlock();
    for (int j = 0; j < len; j += 8) {
//        uint32_t ret = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, adr + j, *(uint64_t *)(buf + j));
//        switch (ret)
//        {
//        case HAL_OK:
//            break;
//        case HAL_TIMEOUT:
//            logger.error("HAL_FLASH_Program() timeout!\n");
//            break;
//        case HAL_ERROR:
//            logger.error("HAL_FLASH_Program() error 0x%08x\n",
//                         HAL_FLASH_GetError());
//            break;
//        default:
//            logger.error("HAL_FLASH_Program() returned unknown status %lu\n", ret);
//        }
    }
//    HAL_FLASH_Lock();
    return 0;
}


int erasePage(uint32_t adr, uint32_t pageNrs) {
//    FLASH_EraseInitTypeDef f;
//    for (uint32_t i = 0; i < pageNrs; i++)
//        UnProtectRWpages(adr + i);
//    HAL_FLASH_Unlock();
//    f.TypeErase = FLASH_TYPEERASE_PAGES;
//    f.Banks = FLASH_BANK_1;
//    f.Page = adr;
//    f.NbPages = pageNrs;
//    //设置PageError
//    uint32_t PageError = 0;
//    //调用擦除函数
//    uint32_t retf = HAL_FLASHEx_Erase(&f, (uint32_t *)&PageError);
//    if ((retf != HAL_OK) || (PageError != 0xffffffff))
//    {
//        logger.error("erase error :0x%x\n", PageError);
//        return -1;
//    }
    return 0;
}

mem_block *boardBase::get_retain() {
#ifdef USE_LFS
    return new retain_lfs("retain1", "retain2");
//#else
//    return new retain_stm32(0x0807f000, 0x0807f800, 2048);
#endif
    return nullptr;
}

int boardBase::clock_diag() {
//    logger.debug("clock= %d \n", HAL_RCC_GetSysClockFreq());
//    logger.debug("HCLK = %d \n", HAL_RCC_GetHCLKFreq());
//    logger.debug("PCLK1 = %d\n", HAL_RCC_GetPCLK1Freq());
//    logger.debug("PCLK2 = %d \n", HAL_RCC_GetPCLK2Freq());
//    RCC_OscInitTypeDef RCC_OscInitStruct;
//    HAL_RCC_GetOscConfig(&RCC_OscInitStruct);
//    if (RCC_OscInitStruct.HSEState == RCC_HSE_ON)
//    {
//        logger.debug("HSE ON.\n");
//    }
//    else
//    {
//        logger.debug("HSE OFF.\n");
//    }
//    if (RCC_OscInitStruct.LSEState == RCC_LSE_ON)
//    {
//        logger.debug("LSE ON");
//    }
//    else
//    {
//        logger.debug("LSE OFF");
//    }
//    logger.debug("SysTick : CTRL=0x%x, LOAD= 0x%x, VAL= 0x%x , CALIB= 0x%x\n",
//                 (volatile long unsigned int)SysTick->CTRL, (volatile long unsigned int)SysTick->LOAD,
//                 (volatile long unsigned int)SysTick->VAL, (volatile long unsigned int)SysTick->CALIB);
    return 0;
}

extern "C"
{
int _write(int file, char *data, int len) {
//    if ((file != STDOUT_FILENO) && (file != STDERR_FILENO)) {
//        errno = EBADF;
//        return -1;
//    }
//    if (rte_data.debug_serial >= 0) {
//        kSerial::get_serial(rte_data.debug_serial)->write((const u8 *) data, len);
//    }
    for (int i = 0; i < len; i++) {
        Serial.write(data[i]);
    }
    return len;
}

void configIPClock() {
}
}

int serial_putchar(char c) {
//    if (rte_data.debug_serial >= 0) {
//        kSerial::get_serial(rte_data.debug_serial)->print(c);
//    }
    Serial.print(c);
    return 0;
}

void boardBase::goto_iap() {

}

#define V25 1.43          // from datasheet
#define VSENSE 3.3 / 4096 // VSENSE value
#define Avg_Slope .0043   // 4.3mV from datasheet

void get_cpu_info() {
//    rte_data.cpu.vref = __LL_ADC_CALC_VREFANALOG_VOLTAGE(analogRead(AVREF), LL_ADC_RESOLUTION_12B);
//    rte_data.cpu.temp = __LL_ADC_CALC_TEMPERATURE(rte_data.cpu.vref, analogRead(ATEMP), LL_ADC_RESOLUTION_12B); // formula from datasheet
//    rte_data.cpu.vbat = __LL_ADC_CALC_DATA_TO_VOLTAGE(rte_data.cpu.vref, analogRead(AVBAT), LL_ADC_RESOLUTION_12B)*3;
}

#ifdef HAL_IRDA_MODULE_ENABLED
void kSerial::setIRDA(int SD_PIN)
{
    _sd_pin = SD_PIN;
    IRDA_HandleTypeDef hirda;
    hirda.Instance = serial->_serial.uart;
    hirda.Init.BaudRate = baud();
    hirda.Init.WordLength = IRDA_WORDLENGTH_8B;
    hirda.Init.Parity = IRDA_PARITY_NONE;
    hirda.Init.Mode = IRDA_MODE_TX_RX;
    hirda.Init.Prescaler = 1;
    hirda.Init.PowerMode = IRDA_POWERMODE_NORMAL;
    hirda.Init.Prescaler = 10;
    if (HAL_IRDA_Init(&hirda) != HAL_OK)
    {
        Error_Handler();
    }
    pinMode(_sd_pin, OUTPUT);
}
#endif
#endif
